package com.finance.system.configure.mvc;

import com.finance.system.support.utils.JwtTokenUtil;
import com.finance.system.configure.websecurity.AuthUser;
import com.finance.system.configure.websecurity.FinanceAuthenticationSuccessHandler;
import com.finance.system.user.entity.JwtPayload;
import com.finance.system.user.entity.UserEntity;
import com.finance.system.user.entity.UserInfo;
import com.finance.system.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

@Component
public class FinanceHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private IUserService userService;
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        AuthUser annotation = parameter.getParameterAnnotation(AuthUser.class);
        return annotation != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory)  {
        HttpServletRequest request = (HttpServletRequest)webRequest.getNativeRequest();
        String token = getTokenFromRequest(request);

        JwtPayload tokenUser = jwtTokenUtil.parsePayload(token);

        UserEntity user = userService.getById(tokenUser.getUserId());

        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setUserName(user.getUserName());
        userInfo.setPhone(user.getPhone());
        userInfo.setEmail(user.getEmail());
        return userInfo;
    }

    private String getTokenFromRequest(HttpServletRequest request) {
        String tokenFromHeader = getTokenFromHeader(request);
        if(StringUtils.isEmpty(tokenFromHeader)){
            tokenFromHeader = getTokenFromCookie(request);
        }
        return tokenFromHeader;
    }

    private String getTokenFromHeader(HttpServletRequest request) {
        String authentication = request.getHeader(FinanceAuthenticationSuccessHandler.TOKEN_KEY);
        return authentication;
    }

    private String getTokenFromCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if(StringUtils.equals(cookie.getName(),FinanceAuthenticationSuccessHandler.TOKEN_KEY)){
                return cookie.getValue();
            }
        }

        return null;
    }
}
